<template>
  <div class="roles-container">
    <!-- 面包屑 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片 -->
    <el-card class="box-card">
      <el-button type="primary" class="addRoleBtn" @click="addDialogVisible = true">添加角色</el-button>
      <!-- 添加角色对话框 -->
      <el-dialog title="添加角色" :visible.sync="addDialogVisible" width="50%" :before-close="handleClose"
        @close="addClearDialog">
        <!-- 对话框主体 -->
        <el-form :model="postInfo" :rules="rules" ref="postInfoRef" label-width="100px">
          <el-form-item label="角色名称" prop="roleName">
            <el-input v-model="postInfo.roleName"></el-input>
          </el-form-item>
          <el-form-item label="角色描述" prop="roleDesc">
            <el-input v-model="postInfo.roleDesc"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="addDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="addRole">确 定</el-button>
        </span>
      </el-dialog>
      <!-- 修改角色信息对话框 -->
      <el-dialog title="修改用户信息" :visible.sync="editDialogVisible" width="50%" :before-close="handleClose"
        @close="editClearDialog">
        <!-- 对话框主体 -->
        <el-form :model="editInfo" :rules="rules" ref="editInfoRef" label-width="100px">
          <el-form-item label="角色名称" prop="roleName">
            <el-input v-model="editInfo.roleName"></el-input>
          </el-form-item>
          <el-form-item label="角色描述" prop="roleDesc">
            <el-input v-model="editInfo.roleDesc"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="editDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="editRole">确 定</el-button>
        </span>
      </el-dialog>
      <!-- 分配角色对话框 -->
      <el-dialog title="分配权限" :visible.sync="settingDialogVisible" width="30%" :before-close="handleClose"
        @close="settingClearDialog">
        <!-- 分配权限列表树 -->
        <el-tree :data="rightsList" :props="defaultProps" show-checkbox node-key="id" default-expand-all
          :default-checked-keys="checkedKeys" ref="rightsListRef">
        </el-tree>
        <span slot="footer" class="dialog-footer">
          <el-button @click="settingDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="addSetting">确 定</el-button>
        </span>
      </el-dialog>
      <el-table :data="rolesList" border stripe style="width: 100%">
        <!-- 权限树 -->
        <el-table-column type="expand">
          <template slot-scope="scope">
            <el-row :class="['bdbottom',index === 0 ? 'bdtop':'']" v-for="(item,index) in scope.row.children"
              :key="item.id">
              <!-- 渲染一级 -->
              <el-col :span="5">
                <el-tag closable @close="removeRightById(scope.row,item.id)">{{item.authName}}</el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!-- 渲染二级和三级 -->
              <el-col :span="19">
                <el-row :class="[subIndex === 0?'':'bdtop']" v-for="(subItem,subIndex) in item.children"
                  :key="subItem.id">
                  <el-col :span="6">
                    <el-tag closable type="success" @close="removeRightById(scope.row,subItem.id)">{{subItem.authName}}
                    </el-tag>
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <el-col :span="18">
                    <el-tag closable v-for="subSubItem,subSubIndex in subItem.children" :key="subSubItem.id"
                      type="warning" @close="removeRightById(scope.row,subSubItem.id)">
                      {{subSubItem.authName}}
                    </el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <!-- 索引 -->
        <el-table-column type="index" label="#">
        </el-table-column>
        <el-table-column prop="roleName" label="角色名称">
        </el-table-column>
        <el-table-column prop="roleDesc" label="角色描述">
        </el-table-column>
        </el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-tooltip effect="dark" content="编辑" placement="top">
              <el-button type="primary" icon="el-icon-edit" circle @click="openEditRole(scope.row)"></el-button>
            </el-tooltip>
            <el-tooltip effect="dark" content="分配权限" placement="top">
              <el-button type="warning" icon="el-icon-setting" circle @click="openSettingRole(scope.row)"></el-button>
            </el-tooltip>
            <el-tooltip effect="dark" content="删除" placement="top">
              <el-button type="danger" icon="el-icon-delete" circle @click="deleteRole(scope.row.id)"></el-button>
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
  </div>
</template>
<script>
  export default {
    name: 'MyRoles',
    data() {
      return {
        roleId: '',
        addDialogVisible: false,
        editDialogVisible: false,
        settingDialogVisible: false,
        rightsList: [],
        rolesList: [],
        postInfo: {
          roleName: '',
          roleDesc: ''
        },
        editInfo: {
          id: '',
          roleName: '',
          roleDesc: ''
        },
        rules: {
          roleName: [{
            required: true,
            message: '请输入角色名称',
            trigger: 'blur'
          }],
          roleDesc: [{
            required: true,
            message: '请输入角色描述',
            trigger: 'blur'
          }]
        },
        defaultProps: {
          children: 'children',
          label: 'authName'
        },
        checkedKeys: []
      }
    },
    created() {
      this.initRolesList()
    },
    methods: {
      async initRolesList() {
        const {
          data: res
        } = await this.$http.get('roles')
        if (res.meta.status !== 200) {
          this.$message({
            showClose: true,
            message: '获取数据失败',
            type: 'error'
          })
        } else {
          this.rolesList = res.data
        }
      },
      handleClose(done) {
        this.$confirm('确认关闭？')
          .then(_ => {
            done();
          })
          .catch(_ => {});
      },
      //清空添加角色对话框
      addClearDialog() {
        this.$refs.postInfoRef.resetFields()
      },
      //清空修改角色对话框
      editClearDialog() {
        this.$refs.editInfoRef.resetFields()
      },
      //添加角色
      async addRole() {
        this.$refs.postInfoRef.validate(async valid => {
          if (!valid) {
            this.$message({
              showClose: true,
              message: '提交的数据非法',
              type: 'error'
            })
          } else {
            //提交数据
            const {
              data: res
            } = await this.$http.post('roles', this.postInfo)
            if (res.meta.status !== 201) {
              this.$message({
                showClose: true,
                message: '添加角色失败',
                type: 'error'
              })
            } else {
              this.$message({
                showClose: true,
                message: '添加角色成功',
                type: 'success'
              })
              this.addDialogVisible = false
              this.addClearDialog()
              this.initRolesList()
            }
          }
        })
      },
      //打开设置权限信息对话框，获取获取权限信息
      async openSettingRole(role) {
        this.roleId = role.id
        const {
          data: res
        } = await this.$http.get('rights/tree')
        if (res.meta.status !== 200) {
          this.$message({
            showClose: true,
            message: '获取数据失败',
            type: 'error'
          })
        } else {
          this.rightsList = res.data
        }
        this.checkedKeys = []
        this.getCheckedKeys(role, this.checkedKeys)
        this.settingDialogVisible = true
      },
      //通过递归获取某个角色已有的权限信息
      getCheckedKeys(node, arr) {
        if (!node.children) {
          return arr.push(node.id)
        } else {
          node.children.forEach(item => this.getCheckedKeys(item, arr))
        }
      },
      //监听分配权限对话框关闭，对checkedKeys进行清空
      settingClearDialog() {
        this.checkedKeys = []
      },
      //增加角色权限
      async addSetting() {
        const keys = [...this.$refs.rightsListRef.getCheckedKeys(), ...this.$refs.rightsListRef.getHalfCheckedKeys()]
        console.log(keys)
        const rids = keys.join(',')
        const {
          data: res
        } = await this.$http.post(`roles/${this.roleId}/rights`, {
          rids: rids
        })
        if (res.meta.status !== 200) {
          this.$message({
            showClose: true,
            message: '修改分配权限失败',
            type: 'error'
          })
        } else {
          this.$message({
            showClose: true,
            message: '修改分配权限成功',
            type: 'success'
          })
          this.settingDialogVisible = false
        }
      },
      //打开修改角色信息对话框，获取角色信息
      openEditRole(editForm) {
        this.editDialogVisible = true
        this.editInfo = editForm
      },
      //提交修改后的角色信息
      editRole() {
        this.$refs.editInfoRef.validate(async valid => {
          if (!valid) {
            this.$message({
              showClose: true,
              message: '提交的数据非法',
              type: 'error'
            })
          } else {
            //提交数据
            const {
              data: res
            } = await this.$http.put('roles/' + this.editInfo.id, this.editInfo)
            if (res.meta.status !== 200) {
              this.$message({
                showClose: true,
                message: '修改角色失败',
                type: 'error'
              })
            } else {
              this.$message({
                showClose: true,
                message: '修改角色成功',
                type: 'success'
              })
              this.editDialogVisible = false
              this.editClearDialog()
              this.initRolesList()
            }
          }
        })
      },
      //删除角色信息
      deleteRole(id) {
        this.$confirm('此操作将永久删除该角色信息, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(async () => {
          const {
            data: res
          } = await this.$http.delete('roles/' + id)
          if (res.meta.status !== 200) {
            this.$message({
              showClose: true,
              message: '删除角色失败',
              type: 'error'
            })
          } else {
            this.$message({
              showClose: true,
              message: '删除角色成功',
              type: 'success'
            })
            this.initRolesList()
          }
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
      },
      //根据id移除对应的权限
      removeRightById(role, rightId) {
        //弹框
        this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(async () => {
          const {
            data: res
          } = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
          if (res.meta.status !== 200) {
            this.$message({
              type: 'error',
              message: '删除失败!'
            })
          } else {
            this.$message({
              type: 'success',
              message: '删除成功!'
            })
            role.children = res.data
          }
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
      }
    }
  }

</script>
<style lang="less" scoped>
  .box-card {
    margin-top: 15px;
    padding: 0;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1) !important;
  }

  .addRoleBtn {
    margin-bottom: 15px;
  }

  .el-tag {
    margin: 10px
  }

  .bdtop {
    border-top: 1px solid #eee;
  }

  .bdbottom {
    border-bottom: 1px solid #eee;
    margin-left: 50px
  }

  .el-row {
    display: flex;
    align-items: center
  }

</style>
